<template>
  <div :style="nodeInput? 'position: relative; height: 100%': ''">
    <div
      class="tree"
      :style="nodeInput ? 'position: absolute; left: 0; top: 0; bottom: 0; right: 0; overflow: auto; padding-bottom: 200px': '' "
    >
      <el-input
        v-if="nodeInput"
        v-model="searchInput"
        placeholder="输入后回车"
        style="position:sticky; top: 0; z-index: 99"
        prefix-icon="el-icon-search"
        @keydown.native="search"
      />
      <el-tree
        ref="tree"
        class="data_tree"
        style="font-size: 14px"
        :show-checkbox="showCheckbox"
        :default-expand-all="expandAll"
        current-node-key="1"
        :data="data"
        :highlight-current="true"
        :expand-on-click-node="false"
        :props="treeConfig"
        :node-key="treeConfig.id"
        @check="getCheckNode"
        @node-click="nodeClick"
        @node-contextmenu="rightClick"
      >
        <span
          slot-scope="{ node, data }"
          class="custom-tree-node"
          style="position:relative"
        >
          <span
            :class="{'el-icon-s-home':showCheckbox&&data.list,'el-icon-user':showCheckbox&&!data.list}"
          >{{ node.label }}</span>
          <transition name="fade">
            <div
              v-if="data[treeConfig.id]==currentIndex[treeConfig.id]&&node.label"
              id="tree_tip"
              ref="treeTip"
              class="tree_tip"
            >
              <span @click.stop="() => append(data)">新增子节点</span>
              <span @click.stop="() => edit(data)">编辑名称</span>
              <span @click.stop="() => remove(data)">删除该节点</span>
            </div>
          </transition>
        </span>
      </el-tree>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    data: {
      required: true
    },
    nodeInput: {
      type: Boolean,
      default: false
    },
    noConfig: {
      type: Boolean,
      default: false
    },
    value: {
      type: String,
      default: ''
    },
    treeConfig: {
      type: Object
    },
    // 是否右击有弹出
    rClick: {
      type: Boolean,
      default: true
    },
    showCheckbox: {
      type: Boolean,
      default: false
    },
    expandAll: {
      type: Boolean,
      default: true
    },
  },
  data() {
    return {
      currentIndex: {},
      searchInput: '',
      searchIndex: null,
      searchData: [],
      expandedKeys: []
    }
  },
  watch: {
    // 搜索框中内容变化，重置当前搜索结果的索引值
    searchInput: function() {
      this.searchIndex = null
    }
  },
  methods: {
    //高亮查询到的节点
    setKey(key){
      this.$nextTick(()=>{
        this.$refs.tree.setCurrentKey(
          key
        )
      })
    },
    rightClick(event, node) {
      if (this.noConfig || !this.rClick) return
      this.currentIndex = node
      this.$nextTick(() => {
        this.$refs.treeTip.style.left = event.clientX + 'px'
        if (window.innerHeight - event.clientY < 150) {
          this.$refs.treeTip.style.top = event.clientY - 95 + 'px'
        } else {
          this.$refs.treeTip.style.top = event.clientY + 'px'
        }
      })
      // 600ms反应时间，保证右键弹出框不会因为鼠标移开而马上消失
      window.setTimeout(() => {
        document.onmousemove = e => {
          let left = document.getElementById('tree_tip').offsetLeft
          let width = document.getElementById('tree_tip').offsetWidth
          let top = document.getElementById('tree_tip').offsetTop
          let height = document.getElementById('tree_tip').offsetHeight
          if (e.clientX < left - 5 || e.clientX > left + width + 5) {
            this.currentIndex = {}
            document.onmousemove = null
          }
          if (e.clientY < top - 5 || e.clientY > top + height + 5) {
            this.currentIndex = {}
            document.onmousemove = null
          }
        }
      }, 600)
    },
    append(data) {
      this.$emit('append', data)
    },
    edit(data) {
      this.$emit('edit', data)
    },
    remove(data) {
      this.$confirm('确认删除?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$emit('remove', data)
      })
    },
    nodeClick(data) {
      this.$emit('input', data[this.treeConfig.id], data)
      this.currentIndex = {}
    },
    getCheckNode() {
      this.$emit('checkNode', this.$refs.tree.getCheckedNodes())
    },
    setCheckNode(data) {
      this.$refs.tree.setCheckedNodes(data)
    },
    setName(datas) {
      //遍历树  将整棵树组成一个数组
      for (var i in datas) {
        this.expandedKeys.push(datas[i])
        if (datas[i].children || datas[i].list) {
          this.setName(datas[i].children || datas[i].list)
        }
      }
    },
    search(e) {
      var theEvent = window.event || e
      var code = theEvent.keyCode || theEvent.which || theEvent.charCode
      if (code != 13) {
        return
      }
      if (this.searchIndex !== null) {
        this.next()
        return
      }
      this.searchIndex = null
      this.expandedKeys = []
      if (this.searchInput) {
        let searchInput = this.searchInput
        this.setName(this.data[0].children || this.data[0].list)
        this.searchData = this.expandedKeys.filter(item => {
          // 可能会有为null的情况
          if (typeof item[this.treeConfig.label] === 'string') {
            return item[this.treeConfig.label].indexOf(searchInput) > -1 //返回符合查询条件的节
          }
        })
        if (this.searchData.length) {
          //存在符合查询条件的节点
          this.searchIndex = 0
          //展开符合条件节点的父节点（使查询节点显示出来）
          // this.defaultEexpandedkeys = getParentsId(this.searchData[0], this.searchTreeData, 'typeId','parentId', 0);
          this.$nextTick(() => {
            //显示完成后执行
            console.log(this.searchData[0][this.treeConfig.id])
            this.$refs.tree.setCurrentKey(
              this.searchData[0][this.treeConfig.id]
            ) //高亮查询到的第一个节点
            // 推算节点大概位置，一个节点所占高度约为30px
            this.expandedKeys.forEach((ele, index) => {
              if (
                ele[this.treeConfig.id] ===
                this.searchData[0][this.treeConfig.id]
              ) {
                document
                  .getElementsByClassName('tree')[0]
                  .scrollTo(0, index * 30)
              }
            })
            this.nodeClick(this.searchData[0])
          })
        } else {
          this.$message.error('未找到任何匹配数据！')
        }
      } else {
        this.$message.error('请输入要查找的内容！')
      }
    },
    // 下一个节点
    next() {
      if (this.searchIndex !== null) {
        this.searchIndex += 1
        this.searchIndex =
          this.searchIndex < this.searchData.length ? this.searchIndex : 0
        // this.defaultEexpandedkeys = getParentsId(this.searchData[this.searchIndex], this.searchTreeData, 'id','pId', 0);
        this.$nextTick(() => {
          this.$refs.tree.setCurrentKey(
            this.searchData[this.searchIndex][this.treeConfig.id]
          )
          this.nodeClick(this.searchData[this.searchIndex])
          this.expandedKeys.forEach((ele, index) => {
            if (
              ele[this.treeConfig.id] ===
              this.searchData[this.searchIndex][this.treeConfig.id]
            ) {
              document.getElementsByClassName('tree')[0].scrollTo(0, index * 30)
            }
          })
        })
      }
    }
  }
}
</script>
<style lang="less" >
.custom-tree-node {
  position: relative;
  .tree_tip {
    color: #666;
    position: fixed;
    background: #fff;
    display: flex;
    flex-direction: column;
    border-radius: 2px;
    z-index: 11;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.3);
    span {
      height: 32px;
      line-height: 32px;
      padding: 0 20px;
      border-radius: 2px;
      transition: all 0.5s;
    }
    span:hover {
      background: #0e3d9c;
      color: #fff;
    }
  }
}
.el-tree {
  background: transparent;
  /deep/.is-current > .el-tree-node__content {
    background: transparent;
    color: #0d3c9a;
  }
}

/* 修改tree样式 */
.tree {
  .el-tree > .el-tree-node > .el-tree-node__content:first-child {
    &::before,
    &::after {
      border: none;
    }
  }
  .el-tree-node .el-tree-node__content {
    height: 30px;
    &::before,
    &::after {
      content: '';
      position: absolute;
      right: auto;
    }
    &::before {
      z-index: 10;
      border-left: 1px solid #e6e6e6;
      bottom: 50px;
      height: 100%;
      top: 0;
      width: 1px;
      margin-left: -5px;
      margin-top: -15px;
    }
    &::after {
      border-top: 1px solid #e6e6e6;
      height: 20px;
      top: 14px;
      width: 10px;
      margin-left: -5px;
    }
  }
  .el-tree .el-tree-node {
    position: relative;
  }
  .fade-enter-active,
  .fade-leave-active {
    transition: opacity 0.4s;
  }
  .fade-enter,
  .fade-leave-to {
    opacity: 0;
  }
}
</style>
